﻿using System.Net;
using System.Security.Cryptography;
using System.Text;
using Aliyun.OSS;
using Aliyun.OSS.Common;
using Furion.DependencyInjection;
using XinGuanERP.Constants.system;
using XinGuanERP.Db;
using XinGuanERP.Services.business.IServices;

namespace XinGuanERP.Services.system;

public class OssService : IOssService, ITransient
{
    private readonly ILogger<OssService> _logger;
    private readonly DefaultDbContext _defaultDbContext;
    public OssService(ILogger<OssService> logger, DefaultDbContext defaultDbContext)
    {
        _logger = logger;
        _defaultDbContext = defaultDbContext;
    }
    public Dictionary<string, object> getOssSign()
    {
        var accessKeyId = "LTAI5tBjDZatWWunAhxLAAFR";
        var accessKeySecret = "Klcm77KdpkIROAl2ffPemK5I1yDshM";
        var endpoint = "oss-cn-hangzhou.aliyuncs.com";
        var bucket = "markdownhexo";
        var host = $"https://{bucket}.{endpoint}";
        var dir = DateTime.Now.ToString("yyyy-MM-dd");
        Dictionary<string, object> respMap = null;
        
        var ossClient = new OssClient(endpoint, accessKeyId, accessKeySecret);
        try
        {
            var expireTime = 30;
            var expireEndTime = DateTime.Now.AddMinutes(expireTime);
            var policyConditions = new PolicyConditions();
            policyConditions.AddConditionItem(PolicyConditions.CondContentLengthRange, 0, 1048576000);
            policyConditions.AddConditionItem(MatchMode.StartWith, PolicyConditions.CondKey, dir);
            
            var postPolicy = ossClient.GeneratePostPolicy(expireEndTime, policyConditions);
            var binaryData = System.Text.Encoding.UTF8.GetBytes(postPolicy);
            var encodedPolicy = Convert.ToBase64String(binaryData);
            
            // 计算签名
            var hmac = new HMACSHA1(System.Text.Encoding.UTF8.GetBytes(accessKeySecret));
            var bytes = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(encodedPolicy));
            var signature = Convert.ToBase64String(bytes);
            respMap = new();
            respMap.Add("OSSAccessKeyId", accessKeyId);
            respMap.Add("policy", encodedPolicy);
            respMap.Add("signature", signature);
            respMap.Add("dir", dir);
            respMap.Add("host", host);
            respMap.Add("expire", expireEndTime);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }

        return respMap;
    }

    private static OssClient _client =
        new OssClient(OssConstant.endpoint, OssConstant.accessKeyId, OssConstant.accessKeySecret);
    public string uploadFile(IFormFile file)
    {
        try
        {
            var fileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + "-" +  file.FileName;
            var key = "xinguan/" + fileName;
            var url = string.Empty;
            var obj = _client.PutObject(OssConstant.bucket, key, file.OpenReadStream());
            if (obj != null && obj.HttpStatusCode == HttpStatusCode.OK)
            {
                url = OssConstant.host + "/" + key;
            }
            return url;
        }
        catch (OssException e)
        {
            _logger.LogError(string.Format(
                "Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3},BucketName:{4},fileName:{5}",
                e.ErrorCode, e.Message, e.RequestId, e.HostId, OssConstant.bucket, file.FileName));
            return null;
        }
        catch (Exception e)
        {
            _logger.LogError(string.Format("Failed with error info: {0},BucketName:{1},fileName:{2}",
                e.Message, OssConstant.bucket, file.FileName));
            return null;
        }
    }
}